package cn.song.util;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 文件工具类
 * 提供文件操作相关的方法
 *
 * @author SongRenShuo
 * @date 2025/01/06
 */
@Slf4j
public class FileUtils {

    private static final String UPLOAD_DIR = "uploads";
    private static final String TEMP_DIR = "temp";
    private static final String EXCEL_DIR = "excel";

    /**
     * 保存上传的文件
     *
     * @param file 上传的文件
     * @param directory 保存目录
     * @return 保存后的文件路径
     * @throws IOException IO异常
     */
    public static String saveUploadFile(MultipartFile file, String directory) throws IOException {
        if (file == null || file.isEmpty()) {
            throw new IOException("文件为空");
        }

        // 创建目录
        String uploadPath = createDirectory(directory);

        // 生成文件名
        String originalFilename = file.getOriginalFilename();
        String extension = getFileExtension(originalFilename);
        String fileName = generateFileName(extension);

        // 保存文件
        Path filePath = Paths.get(uploadPath, fileName);
        Files.write(filePath, file.getBytes());

        log.info("文件保存成功: {}", filePath.toString());
        return filePath.toString();
    }

    /**
     * 创建目录
     *
     * @param directory 目录名
     * @return 目录路径
     */
    public static String createDirectory(String directory) {
        String basePath = System.getProperty("user.dir");
        Path dirPath = Paths.get(basePath, UPLOAD_DIR, directory);

        if (!Files.exists(dirPath)) {
            try {
                Files.createDirectories(dirPath);
                log.info("创建目录: {}", dirPath.toString());
            } catch (IOException e) {
                log.error("创建目录失败: {}", dirPath.toString(), e);
            }
        }

        return dirPath.toString();
    }

    /**
     * 生成文件名
     *
     * @param extension 文件扩展名
     * @return 文件名
     */
    public static String generateFileName(String extension) {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
        String uuid = IdUtil.fastSimpleUUID();
        return String.format("%s_%s.%s", timestamp, uuid, extension);
    }

    /**
     * 获取文件扩展名
     *
     * @param fileName 文件名
     * @return 扩展名
     */
    public static String getFileExtension(String fileName) {
        if (StrUtil.isBlank(fileName)) {
            return "xlsx";
        }

        int lastDotIndex = fileName.lastIndexOf(".");
        if (lastDotIndex == -1) {
            return "xlsx";
        }

        return fileName.substring(lastDotIndex + 1);
    }

    /**
     * 删除文件
     *
     * @param filePath 文件路径
     * @return 是否删除成功
     */
    public static boolean deleteFile(String filePath) {
        if (StrUtil.isBlank(filePath)) {
            return false;
        }

        try {
            File file = new File(filePath);
            if (file.exists()) {
                boolean deleted = file.delete();
                if (deleted) {
                    log.info("文件删除成功: {}", filePath);
                } else {
                    log.warn("文件删除失败: {}", filePath);
                }
                return deleted;
            }
            return true;
        } catch (Exception e) {
            log.error("删除文件失败: {}", filePath, e);
            return false;
        }
    }

    /**
     * 清理临时文件
     *
     * @param directory 目录
     * @param maxAge 最大保留时间（小时）
     */
    public static void cleanTempFiles(String directory, int maxAge) {
        try {
            String tempPath = createDirectory(directory);
            File tempDir = new File(tempPath);

            if (!tempDir.exists()) {
                return;
            }

            File[] files = tempDir.listFiles();
            if (files == null) {
                return;
            }

            long currentTime = System.currentTimeMillis();
            long maxAgeMillis = maxAge * 60 * 60 * 1000L;

            for (File file : files) {
                if (file.isFile()) {
                    long fileAge = currentTime - file.lastModified();
                    if (fileAge > maxAgeMillis) {
                        if (file.delete()) {
                            log.info("清理临时文件: {}", file.getName());
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("清理临时文件失败", e);
        }
    }

    /**
     * 获取文件大小（MB）
     *
     * @param filePath 文件路径
     * @return 文件大小
     */
    public static double getFileSizeMB(String filePath) {
        try {
            File file = new File(filePath);
            if (file.exists()) {
                return file.length() / (1024.0 * 1024.0);
            }
        } catch (Exception e) {
            log.error("获取文件大小失败: {}", filePath, e);
        }
        return 0.0;
    }

    /**
     * 检查文件是否存在
     *
     * @param filePath 文件路径
     * @return 是否存在
     */
    public static boolean fileExists(String filePath) {
        if (StrUtil.isBlank(filePath)) {
            return false;
        }

        File file = new File(filePath);
        return file.exists() && file.isFile();
    }

    /**
     * 获取Excel文件目录
     *
     * @return Excel文件目录
     */
    public static String getExcelDirectory() {
        return createDirectory(EXCEL_DIR);
    }

    /**
     * 获取临时文件目录
     *
     * @return 临时文件目录
     */
    public static String getTempDirectory() {
        return createDirectory(TEMP_DIR);
    }
}
